"""
Copyright (c) 2022 Guangdong University of Technology
PhotLab is licensed under [Open Source License].
You can use this software according to the terms and conditions of the [Open Source License].
You may obtain a copy of [Open Source License] at: [https://open.source.license/]

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.

See the [Open Source License] for more details.

Author: Meng Xiang, Junjiang Xiang
Created: 2023/8/19
Supported by: National Key Research and Development Program of China

"""
import numpy as np
import torch


def Quantize(signal, partitions, codebook):
    indices = []
    quanta = []
    for datum in signal:
        index = 0
        while index < len(partitions) and datum > partitions[index]:
            index += 1
        indices.append(index)
        quanta.append(codebook[index])
    return indices, quanta


def DAC_One_lane(Input, DAC_Resolution_Bits, OUTPUT_VPP):
    A = max(abs(Input))
    codebook = np.linspace(-A, A, 2 ** DAC_Resolution_Bits)
    partition = codebook - (codebook[1] - codebook[0]) / 2
    partition = np.delete(partition, [0])
    Output, I_Samples_Quan = Quantize(Input, partition, codebook)
    Output = Output - np.mean(Output)
    Output = Output / np.max(Output) * OUTPUT_VPP / 2

    return Output


def dac(input, DAC_Resolution_Bits, DAC_OUTPUT_VPP):
    """DAC数模转换器
    Args:
        input[0]: 输入X偏振信号, numpy类型
        input[1]: 输入Y偏振信号, numpy类型
        DAC_Resolution_Bits: DAC分辨率
        DAC_OUTPUT_VPP: VPP峰峰值

    Returns:
        output[0]：输出X偏振信号
        output[1]:输出Y偏振信号
    """
    X_Pol = input[0]
    Y_Pol = input[1]

    DAC_X_I = DAC_One_lane(np.real(X_Pol), DAC_Resolution_Bits, DAC_OUTPUT_VPP)
    DAC_X_Q = DAC_One_lane(np.imag(X_Pol), DAC_Resolution_Bits, DAC_OUTPUT_VPP)
    DAC_Y_I = DAC_One_lane(np.real(Y_Pol), DAC_Resolution_Bits, DAC_OUTPUT_VPP)
    DAC_Y_Q = DAC_One_lane(np.imag(Y_Pol), DAC_Resolution_Bits, DAC_OUTPUT_VPP)
    Tx_Samples_X_DAC = DAC_X_I + 1j * DAC_X_Q
    Tx_Samples_Y_DAC = DAC_Y_I + 1j * DAC_Y_Q
    
    output = [Tx_Samples_X_DAC, Tx_Samples_Y_DAC]

    return output
